//-----------------------------------------------------------------------
// <copyright file="TypedParameter.cs" company="iron9light">
//      Copyright (c) iron9light. All rights reserved.
// </copyright>
// <author>iron9light</author>
//-----------------------------------------------------------------------

namespace EventBrokerExtension
{
    using System;

    using Microsoft.Practices.Unity.Utility;

    /// <summary>
    /// A class for implementing <see cref="MethodParameter"/> classes
    /// that deal in explicit types.
    /// </summary>
    public class TypedParameter : MethodParameter
    {
        private readonly ReflectionHelper parameterReflector;

        /// <summary>
        /// Initializes a new instance of the <see cref="TypedParameter"/> class
        /// that exposes information about the given <paramref name="parameterType"/>.
        /// </summary>
        /// <param name="parameterType">Type of the parameter.</param>
        public TypedParameter(Type parameterType)
        {
            this.parameterReflector = new ReflectionHelper(parameterType);
        }

        /// <summary>
        /// Gets the type of parameter this object represents.
        /// </summary>
        /// <value>The type of the parameter.</value>
        public virtual Type ParameterType
        {
            get { return this.parameterReflector.Type; }
        }

        /// <summary>
        /// Gets name for the type represented by this <see cref="MethodParameter"/>.
        /// This may be an actual type name or a generic argument name.
        /// </summary>
        /// <value>The name of the parameter type.</value>
        public override string ParameterTypeName
        {
            get { return this.parameterReflector.Type.Name; }
        }

        /// <summary>
        /// Test to see if this parameter value has a matching type for the given type.
        /// </summary>
        /// <param name="type">Type to check.</param>
        /// <returns>True if this parameter value is compatible with type <paramref name="type"/>,
        /// false if not.</returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods",
                Justification = "Validation done by Guard class.")]
        public override bool MatchesType(Type type)
        {
            Guard.ArgumentNotNull(type, "type");
            ReflectionHelper candidateReflector = new ReflectionHelper(type);
            if (candidateReflector.IsOpenGeneric && this.parameterReflector.IsOpenGeneric)
            {
                return candidateReflector.Type.GetGenericTypeDefinition() ==
                       this.parameterReflector.Type.GetGenericTypeDefinition();
            }

            return type.IsAssignableFrom(this.parameterReflector.Type);
        }
    }
}